#ifndef __G_BOTS_GAME2CGAME_H__
#define __G_BOTS_GAME2CGAME_H__

// 8 shorts long
// I mean it's encoded in 8 16bits carried in 8 32bits var ;)
// To avoid compiler dependencies, that structure will be transcripted before being transmitted
// Nope, seems to work with win32 compiler (msvc) and qmvs ;)
// That's good enougth for now... so i'll use the brutal/efficient method
#pragma pack( push, game2cgame_struct )
#pragma pack( 1 )

//////////////////////////////////////////////////////////////////////////////////////////
// NOTE: DONT USE "unsigned short"s because LCC doesn't handle them at all.
// NOTE2: Take care with bitfiels, LCC has a weird endianness for them :(
// Shit.

// Big or little? ;)
// Yep, lcc's code behaviour is not coherent...
#ifdef __LCC__
typedef struct {
	unsigned int 
		padding:16,

		grenademode:4,
		weaponmode:4,
		gren2:4,
		gren1:4;
} bots_g2cg_weapons_t;
#else

#if id386 != 1
	#error bots_game2cgame.h: undefined behaviour for an unknown architecture, fix needed.
#endif

typedef struct {
	unsigned int 
		gren1:4,
		gren2:4,
		weaponmode:4,
		grenademode:4,

		padding:16;
} bots_g2cg_weapons_t;
#endif

// All class specific structures are derived from that one
typedef struct {
	// INT 3
	short
		bits, pad0;		// REQ: Always place that bitfield in front for every derived structure 
	int pad[5];			// Fill till max size
} bots_g2cg_generic_t;

// Captain
typedef struct {
	// INT 3
	short
		bits, pad0;
	// INT 4
	bots_g2cg_weapons_t
		weapons;
	// INT 5
	short
		sKeyDistance, pad1;
	// INT 6
	short
		sWarcryDelay, pad2;

	int
		i7,i8;
} bots_g2cg_captain_t;

// Bodyguard
// Coulda pack it a bit more. Bah!
typedef struct {
	// INT 3
	short
		bits, pad0;
	// INT 4
	bots_g2cg_weapons_t
		weapons;
	// INT 5
	short
		sLaserTime, pad1;
	// INT 6
	short	
		sDecoyDelay, pad2;
	// INT 7
	short	
		sProtected, pad3;

	int
		i8;
} bots_g2cg_bodyguard_t;

// Sniper
typedef struct {
	// INT 3
	short
		bits, pad0;
	// INT 4
	short
		sCloakTime, pad1;

	int
		i5,i6,i7,i8;
} bots_g2cg_sniper_t;

// Soldier
typedef struct {
	// INT 3
	short
		bits, pad0;
	// INT 4
	bots_g2cg_weapons_t
		weapons;
	int
		i5,i6,i7,i8;
} bots_g2cg_soldier_t;

// Berzerker
typedef struct {
	// INT 3
	short
		bits, pad0;
	// INT 4
	short
		sQuadTime, pad1;
	// INT 5
	short
		sChargeTime, pad2;
	// INT 6
	short
		sParasites, pad3;

	int
		i7,i8;
} bots_g2cg_berzerker_t;

// Infiltrator
typedef struct {
	// INT 3
	short
		bits, pad0;
	// INT 4
	bots_g2cg_weapons_t
		weapons;
	// INT 5
	short
		sDisguiseTime, pad1;
	// INT 6
	short
		sDisguiseClass, pad2;

	int
		i7,i8;
} bots_g2cg_infiltrator_t;

// Kamikazee
typedef struct {
	// INT 3
	short
		bits, pad0;
	// INT 4
	bots_g2cg_weapons_t
		weapons;
	int
		i5,i6,i7,i8;
} bots_g2cg_kamikazee_t;

// Nurse
typedef struct {
	// INT 3
	short
		bits, pad0;
	// INT 4
	bots_g2cg_weapons_t
		weapons;
	int
		i5,i6,i7,i8;
} bots_g2cg_nurse_t;

// Scientist
typedef struct {
	// INT 3
	short
		bits, pad0;
	// INT 4
	bots_g2cg_weapons_t
		weapons;
	// INT 5
	short
		sKeyDistance, pad1;

	int
		i6,i7,i8;
} bots_g2cg_scientist_t;

//////////////////////////////////////////////////////////////////////////////////////////
// The big one
typedef struct {
	// INT 1
	unsigned char
		ucPromoPoints, ucTechPoints;
	short pad0;

	// INT 2
	//unsigned 
	short 
		ucPowerup,pad1;

	// INT 3-8
	// Argh. LCC doesn't like my anonymous union.
	union  {
		bots_g2cg_generic_t		generic;
		bots_g2cg_captain_t		captain;
		bots_g2cg_bodyguard_t	bodyguard;
		bots_g2cg_sniper_t		sniper;
		bots_g2cg_soldier_t		soldier;
		bots_g2cg_berzerker_t	berzerker;
		bots_g2cg_infiltrator_t	infiltrator;
		bots_g2cg_kamikazee_t	kamikazee;
		bots_g2cg_nurse_t		nurse;
		bots_g2cg_scientist_t	scientist;
	} onion;
} bots_game2cgame_t;
#pragma pack( pop, game2cgame_struct )
 
//////////////////////////////////////////////////////////////////////////////////////////
// Prototypes
#ifndef CGAME_IMPORT_API_VERSION
	// #pragma message(" ** G2CG ** : server side")
	void *bots_g2cg_getClassSection(gentity_t* ent);
	void bots_updateClientData(gentity_t* ent);
	void bots_updateClientData_captain(gentity_t *self, bots_g2cg_captain_t *p);
	void bots_updateClientData_bodyguard(gentity_t *self, bots_g2cg_bodyguard_t *p);
	void bots_updateClientData_sniper(gentity_t *self, bots_g2cg_sniper_t *p);
	void bots_updateClientData_soldier(gentity_t *self, bots_g2cg_soldier_t *p);
	void bots_updateClientData_berzerker(gentity_t *self, bots_g2cg_berzerker_t *p);
	void bots_updateClientData_infiltrator(gentity_t *self, bots_g2cg_infiltrator_t *p);
	void bots_updateClientData_kamikazee(gentity_t *self, bots_g2cg_kamikazee_t *p);
	void bots_updateClientData_nurse(gentity_t *self, bots_g2cg_nurse_t *p);
	void bots_updateClientData_scientist(gentity_t *self, bots_g2cg_scientist_t *p);
#endif
//////////////////////////////////////////////////////////////////////////////////////////
// Some freaking macros
#define BOTS_CLAMP_UC(a)		((a)>255?255:((a)<0?0:(a)))

#define BOTS_SHIFTBIT(val,pos)		(((val)?1:0)<<(pos))
#define BOTS_SETBIT(bits,val,pos)	(bits) = ((bits)&~(1<<(pos)))|BOTS_SHIFTBIT(val,pos)


// Granted, that one is particulary ugly (check the function and you'll get a good idea)
#ifndef CGAME_IMPORT_API_VERSION
	// Server side
	#define BOTS_G2CG_GETCLASSDATA(type,ent) ((type *) bots_g2cg_getClassSection(ent))
#else
	// Client side
	#define BOTS_G2CG_GETCLASSDATA(type)	((type *) &(BOTS_G2CG_GETDATA()->onion))
	#define BOTS_G2CG_GETDATA()				((bots_game2cgame_t *) &cg.predictedPlayerState.stats[STAT_GAME2CGAME])	
	#define STAT_BOTS_GENERAL				STAT_MAX_ARMOR // csfix: Temp hack	
#endif


//////////////////////////////////////////////////////////////////////////////////////////
// Class bitmasks

// Every class (if it makes sense :)) 


// Bodyguard
#define BOTS_G2CG_BODYGUARD_LASERON				0
#define BOTS_G2CG_BODYGUARD_PULSE				1
#define BOTS_G2CG_BODYGUARD_PROTECTING			2

// Sniper
#define BOTS_G2CG_SNIPER_SIGHT					0
#define BOTS_G2CG_SNIPER_CLOAKED				1
#define BOTS_G2CG_SNIPER_CLOAKWALK				2

// Soldier
#define BOTS_G2CG_SOLDIER_CONQUERMODE			0
#define BOTS_G2CG_SOLDIER_CONQUERED				1
#define BOTS_G2CG_SOLDIER_GUIDE					2
#define BOTS_G2CG_SOLDIER_TAG					3

// Berzerker
#define BOTS_G2CG_BERZERKER_AUTOQUAD			0

// Infiltrator
#define BOTS_G2CG_INFILTRATOR_STEAL				0

// Kamikazee
#define BOTS_G2CG_KAMIKAZEE_AUTOREWIRE			0
#define BOTS_G2CG_KAMIKAZEE_LONGRANGE			1
#define BOTS_G2CG_KAMIKAZEE_STICKMODE			2

// Nurse
#define BOTS_G2CG_NURSE_POISON					0

#endif
